package com.heima.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.heima.article.dto.ArticleDto;
import com.heima.article.pojo.Article;
import com.heima.common.constant.ArticleConstants;
import com.heima.file.service.impl.MinIOFileStorageService;
import com.heima.mapper.ArticleMapper;
import com.heima.search.dto.UserSearchDto;
import com.heima.search.pojo.SearchArticleVo;
import com.heima.service.ArticleUploadService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;

/**
 * 将利用模版生成html文件的步骤，定义为异步方法
 *
 * 在此方法上，定义kafka发送端，将dto作为参数发送至search，在那里会将dto接收并存进es中
 *
 */

@Service
@Transactional
@Async
public class ArticleUploadServiceImpl implements ArticleUploadService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    //Freemarker模板引擎
    @Autowired
    private Configuration configuration;

    //用于上传文件至minio
    @Autowired
    private MinIOFileStorageService minioService;

    @Override
    public void upLoadArticle(ArticleDto dto) {

        if (StringUtils.isNotBlank(dto.getContent())) {
            //2.生成html
            //freemarker的模板对象，获取模板
            Template template = null;
            try {
                template = configuration.getTemplate("article.ftl");
                //先对数据模型处理
                HashMap<String, Object> map = new HashMap<>();
                //放进map中，注意key为content，将content文章由字符串转为对象，因为模板文件遍历时按照对象来遍历的
                map.put("content", JSONArray.parseArray(dto.getContent()));

                //创建一个输出流
                StringWriter out = new StringWriter();

                //合成，第一个参数 数据模型，第二个参数  输出流
                template.process(map, out);

                //3.上传至minio
                InputStream in = new ByteArrayInputStream(out.toString().getBytes());
                String path = minioService.uploadHtmlFile("", dto.getId() + "html", in);

                //4.修改ap_article表的static_url字段为minio的路径
                Long articleId = dto.getId();
                LambdaUpdateWrapper<Article> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(Article::getStaticUrl, path);
                updateWrapper.eq(Article::getId, articleId);
                int update = articleMapper.update(null, updateWrapper);
                System.out.println(update);

                //定义发送端，发送至search微服务
                createArticle2ES(dto, path);

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    void createArticle2ES(ArticleDto dto, String path){
        SearchArticleVo vo = new SearchArticleVo();
        BeanUtil.copyProperties(dto, vo);
        vo.setStaticUrl(path);

        //将vo作为参数发送kafka
        kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, JSON.toJSONString(vo));

    }
}
